package com.java.basis.thread.n8.pool;

import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
 * 用来测试线程池的方法
 *
 * @author wangning
 * @create 2022-02-09 17:13
 */
@Slf4j(topic = "c.TestSubmit")
public class TestSubmit {
	public static void main(String[] args) throws ExecutionException, InterruptedException {
//		test01();
//		test02();
//		test03();
		test04();

	}

	/**
	 * 关闭线程的方法
	 */
	private static void test04() throws InterruptedException {
		ExecutorService pool = Executors.newFixedThreadPool(2);
		Future<Integer> res1 = pool.submit(() -> {
			log.debug("task 1 running ...");
			Thread.sleep(1000);
			log.debug("task 1 end");
			return 1;
		});
		Future<Integer> res2 = pool.submit(() -> {
			log.debug("task 2 running ...");
			Thread.sleep(1000);
			log.debug("task 2 end");
			return 1;
		});
		Future<Integer> res3 = pool.submit(() -> {
			log.debug("task 3 running ...");
			Thread.sleep(1000);
			log.debug("task 3 end");
			return 1;
		});
//		Thread.sleep(1000);
		log.debug("shutdown");

//		pool.shutdown();//使用shutdown并不会阻塞主线程，还会向下执行，如果想要等待结果，可以加上以下方法
//		pool.awaitTermination(3, TimeUnit.SECONDS);
		List<Runnable> runnables = pool.shutdownNow();

		log.debug("1111 {}", runnables);

//		Future<Integer> res4 = pool.submit(() -> {
//			log.debug("task 4 running ...");
//			Thread.sleep(1000);
//			log.debug("task 4 end");
//			return 1;
//		});

	}

	/**
	 * 测试 invokeAny 方法
	 */
	private static void test03() throws InterruptedException, ExecutionException {
		ExecutorService pool = Executors.newFixedThreadPool(1);
		String o = pool.invokeAny(Arrays.asList(
				() -> {
					log.debug("begin 1");
					Thread.sleep(1000);
					log.debug("end 1");
					return "1";
				},
				() -> {
					log.debug("begin 2");
					Thread.sleep(500);
					log.debug("end 2");
					return "2";
				},
				() -> {
					log.debug("begin 3");
					Thread.sleep(2000);
					log.debug("end 3");
					return "3";
				}
		));

		log.debug("{}", o);

	}

	/**
	 * 测试 invokeAll 方法
	 */
	private static void test02() throws InterruptedException {
		ExecutorService pool = Executors.newFixedThreadPool(2);
		List<Future<String>> futures = pool.invokeAll(Arrays.asList(
				() -> {
					log.debug("begin");
					Thread.sleep(1000);
					return "1";
				},
				() -> {
					log.debug("begin");
					Thread.sleep(500);
					return "2";
				},
				() -> {
					log.debug("begin");
					Thread.sleep(2000);
					return "3";
				}
		));

		futures.forEach(f -> {
			try {
				log.debug("{}", f.get());
			} catch (InterruptedException | ExecutionException e) {
				e.printStackTrace();
			}
		});

	}

	/**
	 * 用来测试线程池的 submit 方法
	 *
	 * @throws InterruptedException 异常
	 * @throws ExecutionException 异常
	 */
	private static void test01() throws InterruptedException, ExecutionException {
		ExecutorService pool = Executors.newFixedThreadPool(2);
		Future<String> future  = pool.submit(new Callable<String>() {
			@Override
			public String call() throws Exception {
				log.debug("running...");

				Thread.sleep(1000);
				return "ok";
			}

		});

		log.debug("future {}", future.get());
	}
}
